/*********************
* Author:Dzlua
* QQ:505544956
* time:2016/11/11
*/
#include "ScrollBar.h"
#include "../edui.h"

EDUI_NAMESPACE_BEGIN

ScrollBar* ScrollBar::GetInterface()
{
    ScrollBar* scrollBar = new ScrollBar;
#ifdef EDUI_TEST_NEW_DELETE
    ++m_newdeleteNum;
    Log("[ScrollBar] new scrollBar : %d", scrollBar);
#endif
#ifdef EDUI_USE_LUAPLUS
    LuaMgrPtr->Add("ScrollBar", scrollBar);
#endif
    return scrollBar;
}

void ScrollBar::Release()
{
#ifdef EDUI_TEST_NEW_DELETE
    --m_newdeleteNum;
    Log("[ScrollBar] delete scrollBar : %s, %d", this->GetName(), this);
#endif
#ifdef EDUI_USE_LUAPLUS
    LuaMgrPtr->Remove(this);
#endif
    delete this;
}

ScrollBar* ScrollBar::ToScrollBar(Control* ctrl)
{
    return dynamic_cast<ScrollBar*>(ctrl);
}

ScrollBar::ScrollBar() : m_btn1State(BUTTON_STATE_NORMAL), m_btn2State(BUTTON_STATE_NORMAL)
{}

ScrollBar::~ScrollBar()
{}

bool ScrollBar::SetButton1Inset(const Rect1* inset)
{
    if (!inset) return false;
    m_btn1Inset = *inset;
    return true;
}

Rect1 ScrollBar::GetButton1Inset() const
{
    return m_btn1Inset;
}

bool ScrollBar::SetButton2Inset(const Rect1* inset)
{
    if (!inset) return false;
    m_btn2Inset = *inset;
    return true;
}

Rect1 ScrollBar::GetButton2Inset() const
{
    return m_btn2Inset;
}

Rect ScrollBar::GetBarBkRect()
{
    Rect rc = this->GetImageDrawRect(0, 0);
    if (m_type % 2 == 0){
        rc.x += m_btn1Inset.l + m_btn1Size.w + m_btn1Inset.r + m_barInset.l;
        rc.y += m_barInset.t;
        rc.w = rc.w - m_btn1Inset.l - m_btn1Size.w - m_btn1Inset.r - m_btn2Inset.l - m_btn2Size.w - m_btn2Inset.r - m_barInset.l - m_barInset.r;
        rc.h = rc.h - m_barInset.t - m_barInset.b;
    } else {
        rc.x += m_barInset.l;
        rc.y += m_btn1Inset.t + m_btn1Size.h + m_btn1Inset.b + m_barInset.t;
        rc.w = rc.w - m_barInset.l - m_barInset.r;
        rc.h = rc.h - m_btn1Inset.t - m_btn1Size.h + m_btn1Inset.b - m_btn2Inset.t - m_btn2Size.h - m_btn2Inset.b - m_barInset.t - m_barInset.b;
    }
    return rc;
}

Rect ScrollBar::GetButton1Rect()
{
    Rect rc = this->GetImageDrawRect(0, 0);
    if (m_type % 2 == 0){
        rc.x += m_btn1Inset.l;
        rc.y += m_btn1Inset.t;
        rc.w = m_btn1Size.w;
        rc.h = m_btn1Size.h;
    } else {
        rc.x += m_btn1Inset.l;
        rc.y += m_btn1Inset.t;
        rc.w = m_btn1Size.w;
        rc.h = m_btn1Size.h;
    }
    return rc;
}

Rect ScrollBar::GetButton2Rect()
{
    Rect rc = this->GetImageDrawRect(0, 0);
    if (m_type % 2 == 0){
        rc.x = rc.x + rc.w - m_btn2Size.w - m_btn2Inset.r;
        rc.y += m_btn2Inset.t;
        rc.w = m_btn2Size.w;
        rc.h = m_btn2Size.h;
    } else {
        rc.x += m_btn2Inset.l;
        rc.y = rc.y + rc.h - m_btn2Size.h - m_btn2Inset.b;
        rc.w = m_btn2Size.w;
        rc.h = m_btn2Size.h;
    }
    return rc;
}

bool ScrollBar::SetButton1Size(const Size* sz)
{
    if (!sz) return false;
    m_btn1Size = *sz;
    return true;
}

Size ScrollBar::GetButton1Size() const
{
    return m_btn1Size;
}

bool ScrollBar::SetButton2Size(const Size* sz)
{
    if (!sz) return false;
    m_btn2Size = *sz;
    return true;
}

Size ScrollBar::GetButton2Size() const
{
    return m_btn2Size;
}

void ScrollBar::OnButton1Click()
{
    if (m_type == 0) this->SetValue(m_val - m_step);
    else if (m_type == 1) this->SetValue(m_val + m_step);
    else if (m_type == 2) this->SetValue(m_val + m_step);
    else if (m_type == 3) this->SetValue(m_val - m_step);
    this->DoEvent(EVENT_CLICK, (void*)1);
}

void ScrollBar::OnButton2Click()
{
    if (m_type == 0) this->SetValue(m_val + m_step);
    else if (m_type == 1) this->SetValue(m_val - m_step);
    else if (m_type == 2) this->SetValue(m_val - m_step);
    else if (m_type == 3) this->SetValue(m_val + m_step);
    this->DoEvent(EVENT_CLICK, (void*)2);
}

bool ScrollBar::HandleMsgButton(Msg* msg, Rect& rc, ButtonState& state, ButtonClickFunc fun)
{
    bool bReDraw = false;
    bool bHandled = false;
    if (msg->msg == MSG_WND_LEAVE){
        if (state != BUTTON_STATE_NORMAL){
            state = BUTTON_STATE_NORMAL;
            bReDraw = true;
        }
    } else if (msg->msg == MSG_MOUSE_MOVE){
        MouseMoveMsg *evt = &msg->motion;
        if (rc.IsInRect(evt->x, evt->y)){
            if (state !=  BUTTON_STATE_HOT){
                state =  BUTTON_STATE_HOT;
                bReDraw = true;
            }
            bHandled = true;
        } else {
            if (state !=  BUTTON_STATE_NORMAL){
                state =  BUTTON_STATE_NORMAL;
                bReDraw = true;
            }
        }
    } else if (msg->msg == MSG_MOUSE_BUTTON_DOWN){
        MouseButtonMsg *evt = &msg->button;
        if (rc.IsInRect(evt->x, evt->y)){
            if (state !=  BUTTON_STATE_PRESSED){
                state =  BUTTON_STATE_PRESSED;
                bReDraw = true;
            }
            (this->*fun)();
            bHandled = true;
        }
    } else if (msg->msg == MSG_MOUSE_BUTTON_UP){
        MouseButtonMsg *evt = &msg->button;
        if (rc.IsInRect(evt->x, evt->y)){
            if (state !=  BUTTON_STATE_HOT){
                state =  BUTTON_STATE_HOT;
                bReDraw = true;
            }
            bHandled = true;
        } else {
            if (state !=  BUTTON_STATE_NORMAL){
                state =  BUTTON_STATE_NORMAL;
                bReDraw = true;
            }
        }
    }

    if (bReDraw) this->Invaldate(&rc);
    return bHandled;
}

bool ScrollBar::HandleMsg(Msg* msg)
{
    Rect rcBtn1 = this->GetButton1Rect();
    if (rcBtn1.IsOK()) this->HandleMsgButton(msg, rcBtn1, m_btn1State, &ScrollBar::OnButton1Click);
    Rect rcBtn2 = this->GetButton2Rect();
    if (rcBtn2.IsOK()) this->HandleMsgButton(msg, rcBtn2, m_btn2State, &ScrollBar::OnButton2Click);
    return Slider::HandleMsg(msg);
}

void ScrollBar::RenderStatusImages(IRender* render, const Rect* rc)
{
    Slider::RenderStatusImages(render, rc);

    if (!m_bEnabled){
        m_btn1State = BUTTON_STATE_DISABLED;
        m_btn2State = BUTTON_STATE_DISABLED;
    }

    Rect rcBtn1 = this->GetButton1Rect();
    if (rcBtn1.IsOK() && (!rc || rcBtn1.IsUnion(rc))){
        if (m_btn1State == BUTTON_STATE_NORMAL){
            this->DrawImage(render, &m_btn1NoramlImage, &rcBtn1);
        } else if (m_btn1State == BUTTON_STATE_HOT){
            this->DrawImage(render, &m_btn1HotImage, &rcBtn1);
        } else if (m_btn1State == BUTTON_STATE_PRESSED){
            this->DrawImage(render, &m_btn1PressedImage, &rcBtn1);
        } else if (m_btn1State == BUTTON_STATE_DISABLED){
            this->DrawImage(render, &m_btn1DisabledImage, &rcBtn1);
        }
    }

    Rect rcBtn2 = this->GetButton2Rect();
    if (rcBtn2.IsOK() && (!rc || rcBtn2.IsUnion(rc))){
        if (m_btn2State == BUTTON_STATE_NORMAL){
            this->DrawImage(render, &m_btn2NoramlImage, &rcBtn2);
        } else if (m_btn2State == BUTTON_STATE_HOT){
            this->DrawImage(render, &m_btn2HotImage, &rcBtn2);
        } else if (m_btn2State == BUTTON_STATE_PRESSED){
            this->DrawImage(render, &m_btn2PressedImage, &rcBtn2);
        } else if (m_btn2State == BUTTON_STATE_DISABLED){
            this->DrawImage(render, &m_btn2DisabledImage, &rcBtn2);
        }
    }
}

ImageData* ScrollBar::GetDestImageData(const char* value)
{
    if (0 == strcmp(value, "btn1normal")){
        return &m_btn1NoramlImage;
    } else if (0 == strcmp(value, "btn1hot")){
        return &m_btn1HotImage;
    } else if (0 == strcmp(value, "btn1pressed")){
        return &m_btn1PressedImage;
    } else if (0 == strcmp(value, "btn1disabled")){
        return &m_btn1DisabledImage;
    } else if (0 == strcmp(value, "btn2normal")){
        return &m_btn2NoramlImage;
    } else if (0 == strcmp(value, "btn2hot")){
        return &m_btn2HotImage;
    } else if (0 == strcmp(value, "btn2pressed")){
        return &m_btn2PressedImage;
    } else if (0 == strcmp(value, "btn2disabled")){
        return &m_btn2DisabledImage;
    }
    return Slider::GetDestImageData(value);
}

void ScrollBar::SetAttribute(const char* name, const char* value)
{
    if (0 == strcmp(name, "btn1inset")){
        Rect1 rc = ParserRect1(value);
        this->SetButton1Inset(&rc);
    } else if (0 == strcmp(name, "btn2inset")){
        Rect1 rc = ParserRect1(value);
        this->SetButton2Inset(&rc);
    } else if (0 == strcmp(name, "btn1size")){
        Size sz = ParserSize(value);
        this->SetButton1Size(&sz);
    } else if (0 == strcmp(name, "btn2size")){
        Size sz = ParserSize(value);
        this->SetButton2Size(&sz);
    } else {
        Slider::SetAttribute(name, value);
    }
}

void ScrollBar::DoEvent(EventType type, void* data1, void* data2)
{
    switch (type){
        case EVENT_SCROLL : this->evt.scroll.emit(this); break;
        case EVENT_CLICK  : {
            if ((size_t)data1 == 1) this->evt.btn1Click.emit(this);
            else if ((size_t)data1 == 2) this->evt.btn2Click.emit(this);
            break;
        }
    }
#ifdef EDUI_USE_LUAPLUS
    switch (type){
        case EVENT_SCROLL : LuaMgrPtr->DoEvent(this, "scroll"); break;
        case EVENT_CLICK  : {
            if ((size_t)data1 == 1) LuaMgrPtr->DoEvent(this, "btn1Click");
            else if ((size_t)data1 == 2) LuaMgrPtr->DoEvent(this, "btn2Click");
            break;
        }
    }
#endif
}

EDUI_NAMESPACE_END
